using CollabApp.Application.Interfaces;
using CollabApp.Domain.Entities.Game;
using CollabApp.Domain.Services.Game;
using Microsoft.Extensions.Logging;
using System.Text.Json;

namespace CollabApp.Application.Services.Game;

/// <summary>
/// 画线圈地游戏 - 玩家状态管理服务实现
/// 负责管理游戏中玩家的完整状态，包括位置、画线、领地、道具等
/// </summary>
public class PlayerStateService : IPlayerStateService
{
    private readonly IRedisService _redisService;
    private readonly ILogger<PlayerStateService> _logger;

    /// <summary>
    /// Redis键格式
    /// </summary>
    private static class RedisKeys
    {
        public const string PlayerState = "player_state:{0}:{1}"; // gameId:playerId
        public const string GamePlayers = "game_players:{0}"; // gameId
        public const string PlayerTrail = "player_trail:{0}:{1}"; // gameId:playerId
        public const string PlayerTerritories = "player_territories:{0}:{1}"; // gameId:playerId
        public const string PlayerInventory = "player_inventory:{0}:{1}"; // gameId:playerId
        public const string PlayerEffects = "player_effects:{0}:{1}"; // gameId:playerId
        public const string GameRanking = "game_ranking:{0}"; // gameId
        public const string PlayerStats = "player_stats:{0}:{1}"; // gameId:playerId
    }

    /// <summary>
    /// 游戏常量配置
    /// </summary>
    private static class GameConstants
    {
        public const float BaseSpeed = 100f; // 基础速度：像素/秒
        public const float MaxSpeed = 200f; // 最大速度限制
        public const int InvulnerabilityDuration = 5; // 无敌时间：秒
        public const int RespawnDelay = 5; // 复活延迟：秒
        public const float PickupRange = 20f; // 道具拾取范围：像素
        public const int MaxInventorySize = 3; // 最大背包容量
        public const float InitialTerritorySize = 50f; // 初始领地大小
        public const float MinTerritoryArea = 100f; // 最小有效领地面积
        public static readonly string[] PlayerColors = { "red", "blue", "green", "yellow", "purple", "orange", "pink", "cyan" };
    }

    /// <summary>
    /// 构造函数
    /// </summary>
    public PlayerStateService(IRedisService redisService, ILogger<PlayerStateService> logger)
    {
        _redisService = redisService ?? throw new ArgumentNullException(nameof(redisService));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    #region 玩家基础状态管理

    /// <summary>
    /// 获取玩家完整游戏状态
    /// </summary>
    public async Task<PlayerGameState?> GetPlayerStateAsync(Guid gameId, Guid playerId)
    {
        try
        {
            _logger.LogDebug("获取玩家状态 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);

            var stateKey = string.Format(RedisKeys.PlayerState, gameId, playerId);
            var stateData = await _redisService.GetHashAllAsync(stateKey);

            if (!stateData.Any())
            {
                _logger.LogWarning("玩家状态不存在 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
                return null;
            }

            var playerState = new PlayerGameState
            {
                PlayerId = playerId,
                PlayerName = stateData.GetValueOrDefault("player_name", "Unknown"),
                PlayerColor = stateData.GetValueOrDefault("player_color", "red"),
                State = ParsePlayerState(stateData.GetValueOrDefault("state", "Idle")),
                TotalTerritoryArea = float.Parse(stateData.GetValueOrDefault("territory_area", "0")),
                CurrentRank = int.Parse(stateData.GetValueOrDefault("current_rank", "0")),
                IsInvulnerable = bool.Parse(stateData.GetValueOrDefault("is_invulnerable", "false")),
                LastActivity = DateTime.Parse(stateData.GetValueOrDefault("last_activity", DateTime.UtcNow.ToString("O")))
            };

            // 解析当前位置
            if (stateData.TryGetValue("current_position", out var positionStr))
            {
                playerState.CurrentPosition = ParsePosition(positionStr);
            }

            // 解析出生点
            if (stateData.TryGetValue("spawn_point", out var spawnStr))
            {
                playerState.SpawnPoint = ParsePosition(spawnStr);
            }

            // 解析无敌结束时间
            if (stateData.TryGetValue("invulnerability_end", out var invulEndStr) && 
                DateTime.TryParse(invulEndStr, out var invulEndTime))
            {
                playerState.InvulnerabilityEndTime = invulEndTime;
            }

            // 获取当前轨迹
            playerState.CurrentTrail = await GetPlayerTrailAsync(gameId, playerId);

            // 获取拥有的领地
            playerState.OwnedTerritories = await GetPlayerTerritoriesAsync(gameId, playerId);

            // 获取背包物品
            playerState.Inventory = await GetPlayerInventoryAsync(gameId, playerId);

            // 获取活跃效果
            playerState.ActiveEffects = await GetPlayerActiveEffectsAsync(gameId, playerId);

            // 获取统计信息
            playerState.Statistics = await GetPlayerStatisticsAsync(gameId, playerId);

            return playerState;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取玩家状态失败 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
            return null;
        }
    }

    /// <summary>
    /// 获取游戏中所有玩家状态
    /// </summary>
    public async Task<List<PlayerGameState>> GetAllPlayerStatesAsync(Guid gameId)
    {
        try
        {
            _logger.LogDebug("获取所有玩家状态 - GameId: {GameId}", gameId);

            var playersKey = string.Format(RedisKeys.GamePlayers, gameId);
            var playerIds = await _redisService.GetSetMembersAsync(playersKey);

            var playerStates = new List<PlayerGameState>();

            // 并发获取所有玩家状态
            var tasks = playerIds.Select(async playerIdStr =>
            {
                if (Guid.TryParse(playerIdStr, out var playerId))
                {
                    var state = await GetPlayerStateAsync(gameId, playerId);
                    return state;
                }
                return null;
            });

            var results = await Task.WhenAll(tasks);
            playerStates.AddRange(results.Where(state => state != null)!);

            // 按排名排序
            playerStates.Sort((a, b) => a.CurrentRank.CompareTo(b.CurrentRank));

            _logger.LogDebug("获取到 {Count} 个玩家状态 - GameId: {GameId}", playerStates.Count, gameId);
            return playerStates;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取所有玩家状态失败 - GameId: {GameId}", gameId);
            return new List<PlayerGameState>();
        }
    }

    /// <summary>
    /// 初始化玩家游戏状态
    /// </summary>
    public async Task<PlayerInitResult> InitializePlayerStateAsync(Guid gameId, Guid playerId, string playerName)
    {
        try
        {
            _logger.LogInformation("初始化玩家状态 - GameId: {GameId}, PlayerId: {PlayerId}, Name: {Name}", 
                gameId, playerId, playerName);

            // 验证参数
            if (string.IsNullOrWhiteSpace(playerName))
            {
                return new PlayerInitResult
                {
                    Success = false,
                    Errors = { "玩家名称不能为空" }
                };
            }

            // 检查玩家是否已存在
            var existingState = await GetPlayerStateAsync(gameId, playerId);
            if (existingState != null)
            {
                return new PlayerInitResult
                {
                    Success = false,
                    Errors = { "玩家已经存在于游戏中" }
                };
            }

            // 分配玩家颜色和编号
            var playerNumber = await GetNextPlayerNumberAsync(gameId);
            if (playerNumber > GameConstants.PlayerColors.Length)
            {
                return new PlayerInitResult
                {
                    Success = false,
                    Errors = { "游戏人数已满" }
                };
            }

            var assignedColor = GameConstants.PlayerColors[playerNumber - 1];

            // 计算出生点
            var spawnPoint = CalculateSpawnPoint(gameId, playerNumber);

            // 创建初始领地
            var initialTerritory = CreateInitialTerritory(playerId, spawnPoint, assignedColor);

            // 保存玩家状态
            await SavePlayerStateAsync(gameId, playerId, new PlayerGameState
            {
                PlayerId = playerId,
                PlayerName = playerName,
                PlayerColor = assignedColor,
                CurrentPosition = spawnPoint,
                SpawnPoint = spawnPoint,
                State = PlayerDrawingState.Idle,
                TotalTerritoryArea = initialTerritory.Area,
                CurrentRank = playerNumber,
                OwnedTerritories = { initialTerritory },
                LastActivity = DateTime.UtcNow,
                Statistics = new PlayerGameStatistics
                {
                    GameStartTime = DateTime.UtcNow,
                    LastActivity = DateTime.UtcNow
                }
            });

            // 将玩家添加到游戏玩家集合
            var playersKey = string.Format(RedisKeys.GamePlayers, gameId);
            await _redisService.SetAddAsync(playersKey, playerId.ToString());

            // 更新游戏排名
            await UpdateGameRankingAsync(gameId);

            _logger.LogInformation("玩家初始化成功 - GameId: {GameId}, PlayerId: {PlayerId}, Color: {Color}, Number: {Number}", 
                gameId, playerId, assignedColor, playerNumber);

            return new PlayerInitResult
            {
                Success = true,
                AssignedColor = assignedColor,
                SpawnPoint = spawnPoint,
                InitialTerritory = initialTerritory,
                PlayerNumber = playerNumber,
                Messages = { $"玩家 {playerName} 成功加入游戏，分配颜色：{assignedColor}" }
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "初始化玩家状态失败 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
            return new PlayerInitResult
            {
                Success = false,
                Errors = { "初始化玩家状态时发生内部错误" }
            };
        }
    }

    #endregion

    #region 移动和画线系统

    /// <summary>
    /// 更新玩家位置并处理移动逻辑
    /// </summary>
    public async Task<PositionUpdateResult> UpdatePlayerPositionAsync(
        Guid gameId, 
        Guid playerId, 
        Position newPosition, 
        DateTime timestamp, 
        bool isDrawing = false)
    {
        try
        {
            _logger.LogDebug("更新玩家位置 - GameId: {GameId}, PlayerId: {PlayerId}, Position: ({X},{Y}), Drawing: {Drawing}", 
                gameId, playerId, newPosition.X, newPosition.Y, isDrawing);

            // 获取玩家当前状态
            var playerState = await GetPlayerStateAsync(gameId, playerId);
            if (playerState == null)
            {
                return new PositionUpdateResult
                {
                    Success = false,
                    Errors = { "玩家不存在" }
                };
            }

            // 检查玩家是否可以移动
            if (!CanPlayerMove(playerState))
            {
                return new PositionUpdateResult
                {
                    Success = false,
                    OldPosition = playerState.CurrentPosition,
                    NewPosition = playerState.CurrentPosition,
                    Errors = { $"玩家当前状态 {playerState.State} 不允许移动" }
                };
            }

            var oldPosition = playerState.CurrentPosition;
            var distanceMoved = CalculateDistance(oldPosition, newPosition);
            var timeDelta = (timestamp - playerState.LastActivity).TotalSeconds;
            var currentSpeed = timeDelta > 0 ? (float)(distanceMoved / timeDelta) : 0f;

            // 速度检查（防作弊）
            var maxAllowedSpeed = CalculateMaxSpeed(playerState);
            if (currentSpeed > maxAllowedSpeed * 1.2f) // 允许20%的网络延迟误差
            {
                return new PositionUpdateResult
                {
                    Success = false,
                    OldPosition = oldPosition,
                    NewPosition = oldPosition,
                    CurrentSpeed = currentSpeed,
                    Errors = { $"移动速度过快：{currentSpeed:F1} > {maxAllowedSpeed:F1}" }
                };
            }

            // 边界检查
            if (!IsPositionInBounds(newPosition))
            {
                return new PositionUpdateResult
                {
                    Success = false,
                    OldPosition = oldPosition,
                    NewPosition = oldPosition,
                    CollisionDetected = true,
                    CollisionInfo = new PlayerCollisionInfo
                    {
                        Type = DrawingGameCollisionType.BoundaryHit,
                        CollisionPoint = newPosition,
                        Description = "撞到地图边界"
                    },
                    Errors = { "移动超出地图边界" }
                };
            }

            var result = new PositionUpdateResult
            {
                Success = true,
                OldPosition = oldPosition,
                NewPosition = newPosition,
                DistanceMoved = distanceMoved,
                CurrentSpeed = currentSpeed
            };

            // 如果正在画线，添加轨迹点
            if (isDrawing && playerState.State == PlayerDrawingState.Drawing)
            {
                await AddTrailPointAsync(gameId, playerId, newPosition, timestamp);
                result.Events.Add("轨迹点已添加");
            }

            // 更新玩家位置和活动时间
            await UpdatePlayerPositionInRedisAsync(gameId, playerId, newPosition, timestamp, distanceMoved);

            // 更新统计信息
            await UpdatePlayerStatisticsAsync(gameId, playerId, stats =>
            {
                stats.TotalDistanceMoved += distanceMoved;
                stats.LastActivity = timestamp;
            });

            _logger.LogDebug("玩家位置更新成功 - GameId: {GameId}, PlayerId: {PlayerId}, Distance: {Distance:F2}", 
                gameId, playerId, distanceMoved);

            return result;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "更新玩家位置失败 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
            return new PositionUpdateResult
            {
                Success = false,
                Errors = { "更新位置时发生内部错误" }
            };
        }
    }

    /// <summary>
    /// 玩家开始画线
    /// </summary>
    public async Task<DrawingStartResult> StartDrawingAsync(Guid gameId, Guid playerId, Position startPosition)
    {
        try
        {
            _logger.LogInformation("玩家开始画线 - GameId: {GameId}, PlayerId: {PlayerId}, Position: ({X},{Y})", 
                gameId, playerId, startPosition.X, startPosition.Y);

            // 获取玩家状态
            var playerState = await GetPlayerStateAsync(gameId, playerId);
            if (playerState == null)
            {
                return new DrawingStartResult
                {
                    Success = false,
                    Errors = { "玩家不存在" }
                };
            }

            // 检查玩家是否可以开始画线
            if (!CanPlayerStartDrawing(playerState))
            {
                return new DrawingStartResult
                {
                    Success = false,
                    Errors = { $"玩家当前状态 {playerState.State} 不允许开始画线" }
                };
            }

            // 验证开始位置是否在玩家领地内
            if (!IsPositionInPlayerTerritory(startPosition, playerState.OwnedTerritories))
            {
                return new DrawingStartResult
                {
                    Success = false,
                    Errors = { "只能从自己的领地内开始画线" }
                };
            }

            // 清空之前的轨迹
            await ClearPlayerTrailAsync(gameId, playerId);

            // 更新玩家状态为画线中
            await UpdatePlayerStateInRedisAsync(gameId, playerId, PlayerDrawingState.Drawing);

            // 添加起始点到轨迹
            var startTime = DateTime.UtcNow;
            await AddTrailPointAsync(gameId, playerId, startPosition, startTime);

            // 更新统计信息
            await UpdatePlayerStatisticsAsync(gameId, playerId, stats =>
            {
                stats.LastActivity = startTime;
            });

            _logger.LogInformation("玩家开始画线成功 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);

            return new DrawingStartResult
            {
                Success = true,
                StartPosition = startPosition,
                StartTime = startTime,
                Messages = { "开始画线" }
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "玩家开始画线失败 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
            return new DrawingStartResult
            {
                Success = false,
                Errors = { "开始画线时发生内部错误" }
            };
        }
    }

    /// <summary>
    /// 玩家停止画线并尝试圈地
    /// </summary>
    public async Task<DrawingEndResult> StopDrawingAsync(Guid gameId, Guid playerId, Position endPosition)
    {
        try
        {
            _logger.LogInformation("玩家停止画线 - GameId: {GameId}, PlayerId: {PlayerId}, Position: ({X},{Y})", 
                gameId, playerId, endPosition.X, endPosition.Y);

            // 获取玩家状态
            var playerState = await GetPlayerStateAsync(gameId, playerId);
            if (playerState == null)
            {
                return new DrawingEndResult
                {
                    Success = false,
                    Errors = { "玩家不存在" }
                };
            }

            // 验证玩家确实在画线状态
            if (playerState.State != PlayerDrawingState.Drawing)
            {
                return new DrawingEndResult
                {
                    Success = false,
                    Errors = { "玩家不在画线状态" }
                };
            }

            // 获取当前轨迹
            var currentTrail = await GetPlayerTrailAsync(gameId, playerId);
            if (currentTrail.Count < 3) // 至少需要3个点才能形成有效轨迹
            {
                await StopDrawingWithoutCapture(gameId, playerId);
                return new DrawingEndResult
                {
                    Success = false,
                    CompletedTrail = currentTrail,
                    Errors = { "轨迹点数不足，无法圈地" }
                };
            }

            // 添加结束点
            currentTrail.Add(endPosition);

            // 检查是否形成闭合回路
            var isClosedLoop = IsTrailClosedLoop(currentTrail, playerState.OwnedTerritories);
            if (!isClosedLoop)
            {
                await StopDrawingWithoutCapture(gameId, playerId);
                return new DrawingEndResult
                {
                    Success = false,
                    CompletedTrail = currentTrail,
                    IsClosedLoop = false,
                    Errors = { "轨迹未形成闭合回路" }
                };
            }

            // 计算新领地面积
            var newTerritory = CalculateNewTerritory(playerId, currentTrail, playerState.PlayerColor);
            if (newTerritory.Area < GameConstants.MinTerritoryArea)
            {
                await StopDrawingWithoutCapture(gameId, playerId);
                return new DrawingEndResult
                {
                    Success = false,
                    CompletedTrail = currentTrail,
                    IsClosedLoop = true,
                    AreaGained = newTerritory.Area,
                    Errors = { $"圈地面积过小：{newTerritory.Area:F1} < {GameConstants.MinTerritoryArea}" }
                };
            }

            // 保存新领地
            await AddPlayerTerritoryAsync(gameId, playerId, newTerritory);

            // 更新玩家总领地面积
            var newTotalArea = playerState.TotalTerritoryArea + newTerritory.Area;
            await UpdatePlayerTerritoryAreaAsync(gameId, playerId, newTotalArea);

            // 清除轨迹并回到Idle状态
            await StopDrawingWithoutCapture(gameId, playerId);

            // 更新游戏排名
            await UpdateGameRankingAsync(gameId);

            // 更新统计信息
            await UpdatePlayerStatisticsAsync(gameId, playerId, stats =>
            {
                stats.TerritoryCaptures++;
                stats.MaxTerritoryArea = Math.Max(stats.MaxTerritoryArea, newTotalArea);
                stats.LastActivity = DateTime.UtcNow;
            });

            _logger.LogInformation("玩家圈地成功 - GameId: {GameId}, PlayerId: {PlayerId}, Area: {Area:F1}", 
                gameId, playerId, newTerritory.Area);

            return new DrawingEndResult
            {
                Success = true,
                EndPosition = endPosition,
                CompletedTrail = currentTrail,
                NewTerritory = newTerritory,
                AreaGained = newTerritory.Area,
                IsClosedLoop = true,
                Messages = { $"圈地成功，获得面积：{newTerritory.Area:F1}" }
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "玩家停止画线失败 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
            return new DrawingEndResult
            {
                Success = false,
                Errors = { "停止画线时发生内部错误" }
            };
        }
    }

    #endregion

    #region 私有辅助方法

    /// <summary>
    /// 解析玩家状态枚举
    /// </summary>
    private static PlayerDrawingState ParsePlayerState(string stateStr)
    {
        return Enum.TryParse<PlayerDrawingState>(stateStr, true, out var state) ? state : PlayerDrawingState.Idle;
    }

    /// <summary>
    /// 解析位置信息
    /// </summary>
    private static Position ParsePosition(string positionStr)
    {
        try
        {
            return JsonSerializer.Deserialize<Position>(positionStr) ?? new Position();
        }
        catch
        {
            return new Position();
        }
    }

    /// <summary>
    /// 获取玩家轨迹
    /// </summary>
    private async Task<List<Position>> GetPlayerTrailAsync(Guid gameId, Guid playerId)
    {
        try
        {
            var trailKey = string.Format(RedisKeys.PlayerTrail, gameId, playerId);
            var trailData = await _redisService.ListRangeAsync(trailKey);
            return trailData.Select(ParsePosition).ToList();
        }
        catch
        {
            return new List<Position>();
        }
    }

    /// <summary>
    /// 获取玩家领地列表
    /// </summary>
    private async Task<List<Territory>> GetPlayerTerritoriesAsync(Guid gameId, Guid playerId)
    {
        try
        {
            var territoriesKey = string.Format(RedisKeys.PlayerTerritories, gameId, playerId);
            var territoriesData = await _redisService.ListRangeAsync(territoriesKey);
            return territoriesData.Select(data =>
            {
                try
                {
                    return JsonSerializer.Deserialize<Territory>(data) ?? new Territory();
                }
                catch
                {
                    return new Territory();
                }
            }).ToList();
        }
        catch
        {
            return new List<Territory>();
        }
    }

    /// <summary>
    /// 获取玩家背包
    /// </summary>
    private async Task<List<DrawingGameItemType>> GetPlayerInventoryAsync(Guid gameId, Guid playerId)
    {
        try
        {
            var inventoryKey = string.Format(RedisKeys.PlayerInventory, gameId, playerId);
            var inventoryData = await _redisService.ListRangeAsync(inventoryKey);
            return inventoryData.Select(itemStr =>
            {
                return Enum.TryParse<DrawingGameItemType>(itemStr, true, out var itemType) ? itemType : DrawingGameItemType.Lightning;
            }).ToList();
        }
        catch
        {
            return new List<DrawingGameItemType>();
        }
    }

    /// <summary>
    /// 获取玩家活跃效果
    /// </summary>
    private async Task<List<ActiveEffect>> GetPlayerActiveEffectsAsync(Guid gameId, Guid playerId)
    {
        try
        {
            var effectsKey = string.Format(RedisKeys.PlayerEffects, gameId, playerId);
            var effectsData = await _redisService.ListRangeAsync(effectsKey);
            return effectsData.Select(data =>
            {
                try
                {
                    return JsonSerializer.Deserialize<ActiveEffect>(data) ?? new ActiveEffect();
                }
                catch
                {
                    return new ActiveEffect();
                }
            }).Where(effect => !effect.IsExpired).ToList();
        }
        catch
        {
            return new List<ActiveEffect>();
        }
    }

    /// <summary>
    /// 获取玩家统计信息
    /// </summary>
    private async Task<PlayerGameStatistics> GetPlayerStatisticsAsync(Guid gameId, Guid playerId)
    {
        try
        {
            var statsKey = string.Format(RedisKeys.PlayerStats, gameId, playerId);
            var statsData = await _redisService.GetHashAllAsync(statsKey);

            if (!statsData.Any())
            {
                return new PlayerGameStatistics
                {
                    GameStartTime = DateTime.UtcNow,
                    LastActivity = DateTime.UtcNow
                };
            }

            return new PlayerGameStatistics
            {
                Deaths = int.Parse(statsData.GetValueOrDefault("deaths", "0")),
                Kills = int.Parse(statsData.GetValueOrDefault("kills", "0")),
                MaxTerritoryArea = float.Parse(statsData.GetValueOrDefault("max_territory_area", "0")),
                TotalDistanceMoved = float.Parse(statsData.GetValueOrDefault("total_distance_moved", "0")),
                ItemsUsed = int.Parse(statsData.GetValueOrDefault("items_used", "0")),
                ItemsPickedUp = int.Parse(statsData.GetValueOrDefault("items_picked_up", "0")),
                TerritoryCaptures = int.Parse(statsData.GetValueOrDefault("territory_captures", "0")),
                GameStartTime = DateTime.Parse(statsData.GetValueOrDefault("game_start_time", DateTime.UtcNow.ToString("O"))),
                LastActivity = DateTime.Parse(statsData.GetValueOrDefault("last_activity", DateTime.UtcNow.ToString("O")))
            };
        }
        catch
        {
            return new PlayerGameStatistics
            {
                GameStartTime = DateTime.UtcNow,
                LastActivity = DateTime.UtcNow
            };
        }
    }

    /// <summary>
    /// 获取下一个玩家编号
    /// </summary>
    private async Task<int> GetNextPlayerNumberAsync(Guid gameId)
    {
        var playersKey = string.Format(RedisKeys.GamePlayers, gameId);
        var playerCount = await _redisService.GetSetCardinalityAsync(playersKey);
        return (int)playerCount + 1;
    }

    /// <summary>
    /// 计算出生点位置
    /// </summary>
    private static Position CalculateSpawnPoint(Guid gameId, int playerNumber)
    {
        // 简化的出生点计算：围绕地图边缘均匀分布
        var angle = (playerNumber - 1) * (2 * Math.PI / 8); // 最多8个玩家，均匀分布
        var radius = 450f; // 距离中心450像素
        var centerX = 500f; // 地图中心X
        var centerY = 500f; // 地图中心Y

        return new Position
        {
            X = centerX + (float)(Math.Cos(angle) * radius),
            Y = centerY + (float)(Math.Sin(angle) * radius)
        };
    }

    /// <summary>
    /// 创建初始领地
    /// </summary>
    private static Territory CreateInitialTerritory(Guid playerId, Position center, string color)
    {
        var size = GameConstants.InitialTerritorySize;
        var halfSize = size / 2;

        return new Territory
        {
            Id = Guid.NewGuid(),
            PlayerId = playerId,
            Color = color,
            Area = size * size,
            CapturedTime = DateTime.UtcNow,
            Boundary = new List<Position>
            {
                new() { X = center.X - halfSize, Y = center.Y - halfSize },
                new() { X = center.X + halfSize, Y = center.Y - halfSize },
                new() { X = center.X + halfSize, Y = center.Y + halfSize },
                new() { X = center.X - halfSize, Y = center.Y + halfSize }
            }
        };
    }

    /// <summary>
    /// 保存玩家状态到Redis
    /// </summary>
    private async Task SavePlayerStateAsync(Guid gameId, Guid playerId, PlayerGameState state)
    {
        var stateKey = string.Format(RedisKeys.PlayerState, gameId, playerId);
        var stateData = new Dictionary<string, string>
        {
            ["player_name"] = state.PlayerName,
            ["player_color"] = state.PlayerColor,
            ["current_position"] = JsonSerializer.Serialize(state.CurrentPosition),
            ["spawn_point"] = JsonSerializer.Serialize(state.SpawnPoint),
            ["state"] = state.State.ToString(),
            ["territory_area"] = state.TotalTerritoryArea.ToString("F2"),
            ["current_rank"] = state.CurrentRank.ToString(),
            ["is_invulnerable"] = state.IsInvulnerable.ToString(),
            ["last_activity"] = state.LastActivity.ToString("O")
        };

        if (state.InvulnerabilityEndTime.HasValue)
        {
            stateData["invulnerability_end"] = state.InvulnerabilityEndTime.Value.ToString("O");
        }

        await _redisService.SetHashMultipleAsync(stateKey, stateData);

        // 保存领地信息
        if (state.OwnedTerritories.Any())
        {
            var territoriesKey = string.Format(RedisKeys.PlayerTerritories, gameId, playerId);
            await _redisService.KeyDeleteAsync(territoriesKey); // 清空旧数据
            foreach (var territory in state.OwnedTerritories)
            {
                await _redisService.ListRightPushAsync(territoriesKey, JsonSerializer.Serialize(territory));
            }
        }

        // 保存统计信息
        await SavePlayerStatisticsAsync(gameId, playerId, state.Statistics);
    }

    /// <summary>
    /// 保存玩家统计信息
    /// </summary>
    private async Task SavePlayerStatisticsAsync(Guid gameId, Guid playerId, PlayerGameStatistics stats)
    {
        var statsKey = string.Format(RedisKeys.PlayerStats, gameId, playerId);
        var statsData = new Dictionary<string, string>
        {
            ["deaths"] = stats.Deaths.ToString(),
            ["kills"] = stats.Kills.ToString(),
            ["max_territory_area"] = stats.MaxTerritoryArea.ToString("F2"),
            ["total_distance_moved"] = stats.TotalDistanceMoved.ToString("F2"),
            ["items_used"] = stats.ItemsUsed.ToString(),
            ["items_picked_up"] = stats.ItemsPickedUp.ToString(),
            ["territory_captures"] = stats.TerritoryCaptures.ToString(),
            ["game_start_time"] = stats.GameStartTime.ToString("O"),
            ["last_activity"] = stats.LastActivity.ToString("O")
        };

        await _redisService.SetHashMultipleAsync(statsKey, statsData);
    }

    /// <summary>
    /// 检查玩家是否可以移动
    /// </summary>
    private static bool CanPlayerMove(PlayerGameState playerState)
    {
        return playerState.State != PlayerDrawingState.Dead && 
               playerState.State != PlayerDrawingState.Respawning;
    }

    /// <summary>
    /// 计算两点间距离
    /// </summary>
    private static float CalculateDistance(Position pos1, Position pos2)
    {
        var dx = pos2.X - pos1.X;
        var dy = pos2.Y - pos1.Y;
        return (float)Math.Sqrt(dx * dx + dy * dy);
    }

    /// <summary>
    /// 计算玩家最大允许速度
    /// </summary>
    private static float CalculateMaxSpeed(PlayerGameState playerState)
    {
        var baseSpeed = GameConstants.BaseSpeed;
        
        // 检查闪电道具效果
        var lightningEffect = playerState.ActiveEffects.FirstOrDefault(e => 
            e.EffectType == DrawingGameItemType.Lightning && !e.IsExpired);
        
        if (lightningEffect != null)
        {
            baseSpeed *= 1.5f; // 速度提升50%
        }

        return Math.Min(baseSpeed, GameConstants.MaxSpeed);
    }

    /// <summary>
    /// 检查位置是否在地图边界内
    /// </summary>
    private static bool IsPositionInBounds(Position position)
    {
        // 假设地图大小为1000x1000
        return position.X >= 0 && position.X <= 1000 && position.Y >= 0 && position.Y <= 1000;
    }

    /// <summary>
    /// 更新玩家在Redis中的位置
    /// </summary>
    private async Task UpdatePlayerPositionInRedisAsync(Guid gameId, Guid playerId, Position newPosition, DateTime timestamp, float distanceMoved)
    {
        var stateKey = string.Format(RedisKeys.PlayerState, gameId, playerId);
        var updates = new Dictionary<string, string>
        {
            ["current_position"] = JsonSerializer.Serialize(newPosition),
            ["last_activity"] = timestamp.ToString("O")
        };

        await _redisService.SetHashMultipleAsync(stateKey, updates);
    }

    /// <summary>
    /// 添加轨迹点
    /// </summary>
    private async Task AddTrailPointAsync(Guid gameId, Guid playerId, Position position, DateTime timestamp)
    {
        var trailKey = string.Format(RedisKeys.PlayerTrail, gameId, playerId);
        await _redisService.ListRightPushAsync(trailKey, JsonSerializer.Serialize(position));
    }

    /// <summary>
    /// 更新玩家统计信息
    /// </summary>
    private async Task UpdatePlayerStatisticsAsync(Guid gameId, Guid playerId, Action<PlayerGameStatistics> updateAction)
    {
        var stats = await GetPlayerStatisticsAsync(gameId, playerId);
        updateAction(stats);
        await SavePlayerStatisticsAsync(gameId, playerId, stats);
    }

    /// <summary>
    /// 检查玩家是否可以开始画线
    /// </summary>
    private static bool CanPlayerStartDrawing(PlayerGameState playerState)
    {
        return playerState.State == PlayerDrawingState.Idle && !playerState.IsInvulnerable;
    }

    /// <summary>
    /// 检查位置是否在玩家领地内
    /// </summary>
    private static bool IsPositionInPlayerTerritory(Position position, List<Territory> territories)
    {
        return territories.Any(territory => IsPointInPolygon(position, territory.Boundary));
    }

    /// <summary>
    /// 点在多边形内判断（射线法）
    /// </summary>
    private static bool IsPointInPolygon(Position point, List<Position> polygon)
    {
        if (polygon.Count < 3) return false;

        bool inside = false;
        int j = polygon.Count - 1;

        for (int i = 0; i < polygon.Count; i++)
        {
            var pi = polygon[i];
            var pj = polygon[j];

            if (((pi.Y > point.Y) != (pj.Y > point.Y)) &&
                (point.X < (pj.X - pi.X) * (point.Y - pi.Y) / (pj.Y - pi.Y) + pi.X))
            {
                inside = !inside;
            }
            j = i;
        }

        return inside;
    }

    /// <summary>
    /// 清除玩家轨迹
    /// </summary>
    private async Task ClearPlayerTrailAsync(Guid gameId, Guid playerId)
    {
        var trailKey = string.Format(RedisKeys.PlayerTrail, gameId, playerId);
        await _redisService.KeyDeleteAsync(trailKey);
    }

    /// <summary>
    /// 更新玩家状态
    /// </summary>
    private async Task UpdatePlayerStateInRedisAsync(Guid gameId, Guid playerId, PlayerDrawingState newState)
    {
        var stateKey = string.Format(RedisKeys.PlayerState, gameId, playerId);
        await _redisService.SetHashAsync(stateKey, "state", newState.ToString());
        await _redisService.SetHashAsync(stateKey, "last_activity", DateTime.UtcNow.ToString("O"));
    }

    /// <summary>
    /// 检查轨迹是否形成闭合回路
    /// </summary>
    private static bool IsTrailClosedLoop(List<Position> trail, List<Territory> playerTerritories)
    {
        if (trail.Count < 3) return false;

        var startPoint = trail.First();
        var endPoint = trail.Last();

        // 简化判断：终点是否靠近起点或者在玩家领地内
        var distanceToStart = CalculateDistance(startPoint, endPoint);
        if (distanceToStart < 30f) return true; // 距离起点30像素内认为闭合

        // 或者终点在玩家的任一领地内
        return playerTerritories.Any(territory => IsPointInPolygon(endPoint, territory.Boundary));
    }

    /// <summary>
    /// 计算新领地
    /// </summary>
    private static Territory CalculateNewTerritory(Guid playerId, List<Position> trail, string color)
    {
        // 使用多边形面积计算（Shoelace公式）
        var area = CalculatePolygonArea(trail);

        return new Territory
        {
            Id = Guid.NewGuid(),
            PlayerId = playerId,
            Color = color,
            Area = area,
            CapturedTime = DateTime.UtcNow,
            Boundary = new List<Position>(trail)
        };
    }

    /// <summary>
    /// 计算多边形面积（Shoelace公式）
    /// </summary>
    private static float CalculatePolygonArea(List<Position> polygon)
    {
        if (polygon.Count < 3) return 0f;

        float area = 0f;
        int j = polygon.Count - 1;

        for (int i = 0; i < polygon.Count; i++)
        {
            area += (polygon[j].X + polygon[i].X) * (polygon[j].Y - polygon[i].Y);
            j = i;
        }

        return Math.Abs(area) / 2f;
    }

    /// <summary>
    /// 添加玩家领地
    /// </summary>
    private async Task AddPlayerTerritoryAsync(Guid gameId, Guid playerId, Territory territory)
    {
        var territoriesKey = string.Format(RedisKeys.PlayerTerritories, gameId, playerId);
        await _redisService.ListRightPushAsync(territoriesKey, JsonSerializer.Serialize(territory));
    }

    /// <summary>
    /// 更新玩家总领地面积
    /// </summary>
    private async Task UpdatePlayerTerritoryAreaAsync(Guid gameId, Guid playerId, float newTotalArea)
    {
        var stateKey = string.Format(RedisKeys.PlayerState, gameId, playerId);
        await _redisService.SetHashAsync(stateKey, "territory_area", newTotalArea.ToString("F2"));
    }

    /// <summary>
    /// 停止画线但不圈地
    /// </summary>
    private async Task StopDrawingWithoutCapture(Guid gameId, Guid playerId)
    {
        await ClearPlayerTrailAsync(gameId, playerId);
        await UpdatePlayerStateInRedisAsync(gameId, playerId, PlayerDrawingState.Idle);
    }

    /// <summary>
    /// 更新游戏排名
    /// </summary>
    private async Task UpdateGameRankingAsync(Guid gameId)
    {
        try
        {
            var allPlayers = await GetAllPlayerStatesAsync(gameId);
            
            // 按领地面积排序
            allPlayers.Sort((a, b) => b.TotalTerritoryArea.CompareTo(a.TotalTerritoryArea));

            // 更新排名
            for (int i = 0; i < allPlayers.Count; i++)
            {
                allPlayers[i].CurrentRank = i + 1;
                var stateKey = string.Format(RedisKeys.PlayerState, gameId, allPlayers[i].PlayerId);
                await _redisService.SetHashAsync(stateKey, "current_rank", (i + 1).ToString());
            }

            // 保存排名到Redis
            var rankingKey = string.Format(RedisKeys.GameRanking, gameId);
            await _redisService.KeyDeleteAsync(rankingKey);
            
            foreach (var player in allPlayers)
            {
                var ranking = new PlayerGameRanking
                {
                    Rank = player.CurrentRank,
                    PlayerId = player.PlayerId,
                    PlayerName = player.PlayerName,
                    PlayerColor = player.PlayerColor,
                    TerritoryArea = player.TotalTerritoryArea,
                    TerritoryCount = player.OwnedTerritories.Count,
                    CurrentState = player.State,
                    LastUpdate = DateTime.UtcNow
                };

                await _redisService.ListRightPushAsync(rankingKey, JsonSerializer.Serialize(ranking));
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "更新游戏排名失败 - GameId: {GameId}", gameId);
        }
    }

    #endregion

    #region 碰撞和战斗系统

    /// <summary>
    /// 处理玩家轨迹被其他玩家碰撞（截断死亡）
    /// </summary>
    public async Task<PlayerCollisionHandleResult> HandleTrailCollisionAsync(
        Guid gameId, 
        Guid victimPlayerId, 
        Position collisionPosition, 
        Guid? attackerPlayerId = null)
    {
        try
        {
            _logger.LogInformation("处理轨迹碰撞 - GameId: {GameId}, Victim: {VictimId}, Attacker: {AttackerId}, Position: ({X},{Y})", 
                gameId, victimPlayerId, attackerPlayerId, collisionPosition.X, collisionPosition.Y);

            // 获取被攻击者状态
            var victimState = await GetPlayerStateAsync(gameId, victimPlayerId);
            if (victimState == null)
            {
                return new PlayerCollisionHandleResult
                {
                    Success = false,
                    Messages = { "被攻击的玩家不存在" }
                };
            }

            // 验证被攻击者正在画线
            if (victimState.State != PlayerDrawingState.Drawing)
            {
                return new PlayerCollisionHandleResult
                {
                    Success = false,
                    Messages = { "被攻击的玩家不在画线状态" }
                };
            }

            // 检查护盾效果
            var shieldEffect = victimState.ActiveEffects.FirstOrDefault(e => 
                e.EffectType == DrawingGameItemType.Shield && !e.IsExpired);

            if (shieldEffect != null)
            {
                // 护盾抵挡攻击
                await RemovePlayerEffectAsync(gameId, victimPlayerId, shieldEffect.Id);
                
                _logger.LogInformation("护盾抵挡攻击 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, victimPlayerId);
                
                return new PlayerCollisionHandleResult
                {
                    Success = true,
                    PlayerDied = false,
                    ShieldBlocked = true,
                    Messages = { "护盾抵挡了攻击" }
                };
            }

            // 获取攻击者信息（如果有）
            string? killerName = null;
            if (attackerPlayerId.HasValue)
            {
                var attackerState = await GetPlayerStateAsync(gameId, attackerPlayerId.Value);
                killerName = attackerState?.PlayerName;

                // 更新攻击者击杀统计
                await UpdatePlayerStatisticsAsync(gameId, attackerPlayerId.Value, stats =>
                {
                    stats.Kills++;
                    stats.LastActivity = DateTime.UtcNow;
                });
            }

            // 获取被攻击者当前轨迹
            var clearedTrail = await GetPlayerTrailAsync(gameId, victimPlayerId);

            // 处理死亡
            var deathReason = attackerPlayerId.HasValue 
                ? $"被玩家 {killerName} 截断"
                : "撞到其他玩家轨迹";

            await HandlePlayerDeathAsync(gameId, victimPlayerId, deathReason, attackerPlayerId, collisionPosition);

            _logger.LogInformation("轨迹碰撞处理完成 - 玩家死亡 - GameId: {GameId}, Victim: {VictimId}", gameId, victimPlayerId);

            return new PlayerCollisionHandleResult
            {
                Success = true,
                PlayerDied = true,
                KillerId = attackerPlayerId,
                KillerName = killerName,
                ClearedTrail = clearedTrail,
                DeathReason = deathReason,
                Messages = { deathReason }
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "处理轨迹碰撞失败 - GameId: {GameId}, VictimId: {VictimId}", gameId, victimPlayerId);
            return new PlayerCollisionHandleResult
            {
                Success = false,
                Messages = { "处理碰撞时发生内部错误" }
            };
        }
    }

    /// <summary>
    /// 处理玩家死亡的完整流程
    /// </summary>
    public async Task<DeathResult> HandlePlayerDeathAsync(
        Guid gameId, 
        Guid playerId, 
        string deathReason, 
        Guid? killerId = null, 
        Position? deathPosition = null)
    {
        try
        {
            _logger.LogInformation("处理玩家死亡 - GameId: {GameId}, PlayerId: {PlayerId}, Reason: {Reason}", 
                gameId, playerId, deathReason);

            // 获取玩家当前状态
            var playerState = await GetPlayerStateAsync(gameId, playerId);
            if (playerState == null)
            {
                return new DeathResult
                {
                    Success = false,
                    Messages = { "玩家不存在" }
                };
            }

            // 如果玩家已经死亡，跳过处理
            if (playerState.State == PlayerDrawingState.Dead || playerState.State == PlayerDrawingState.Respawning)
            {
                return new DeathResult
                {
                    Success = false,
                    Messages = { "玩家已经死亡" }
                };
            }

            var actualDeathPosition = deathPosition ?? playerState.CurrentPosition;
            var respawnTime = DateTime.UtcNow.AddSeconds(GameConstants.RespawnDelay);

            // 获取被清除的轨迹
            var clearedTrail = await GetPlayerTrailAsync(gameId, playerId);

            // 清除玩家轨迹
            await ClearPlayerTrailAsync(gameId, playerId);

            // 设置玩家状态为死亡
            await UpdatePlayerStateInRedisAsync(gameId, playerId, PlayerDrawingState.Dead);

            // 清除临时道具效果（但保留背包物品）
            await ClearPlayerTemporaryEffectsAsync(gameId, playerId);

            // 清除无敌状态
            var stateKey = string.Format(RedisKeys.PlayerState, gameId, playerId);
            var deathUpdates = new Dictionary<string, string>
            {
                ["is_invulnerable"] = "false",
                ["death_position"] = JsonSerializer.Serialize(actualDeathPosition),
                ["respawn_time"] = respawnTime.ToString("O"),
                ["last_activity"] = DateTime.UtcNow.ToString("O")
            };
            await _redisService.SetHashMultipleAsync(stateKey, deathUpdates);

            // 更新死亡统计
            await UpdatePlayerStatisticsAsync(gameId, playerId, stats =>
            {
                stats.Deaths++;
                stats.LastActivity = DateTime.UtcNow;
            });

            // 获取击杀者名称
            string? killerName = null;
            if (killerId.HasValue)
            {
                var killerState = await GetPlayerStateAsync(gameId, killerId.Value);
                killerName = killerState?.PlayerName;
            }

            _logger.LogInformation("玩家死亡处理完成 - GameId: {GameId}, PlayerId: {PlayerId}, RespawnTime: {RespawnTime}", 
                gameId, playerId, respawnTime);

            return new DeathResult
            {
                Success = true,
                DeathReason = deathReason,
                KillerId = killerId,
                KillerName = killerName,
                DeathPosition = actualDeathPosition,
                ClearedTrail = clearedTrail,
                RespawnTime = respawnTime,
                Messages = { $"玩家死亡：{deathReason}，{GameConstants.RespawnDelay}秒后复活" }
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "处理玩家死亡失败 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
            return new DeathResult
            {
                Success = false,
                Messages = { "处理死亡时发生内部错误" }
            };
        }
    }

    /// <summary>
    /// 复活已死亡的玩家
    /// </summary>
    public async Task<RespawnResult> RespawnPlayerAsync(Guid gameId, Guid playerId)
    {
        try
        {
            _logger.LogInformation("复活玩家 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);

            // 获取玩家状态
            var playerState = await GetPlayerStateAsync(gameId, playerId);
            if (playerState == null)
            {
                return new RespawnResult
                {
                    Success = false,
                    Errors = { "玩家不存在" }
                };
            }

            // 验证玩家是否处于死亡状态
            if (playerState.State != PlayerDrawingState.Dead)
            {
                return new RespawnResult
                {
                    Success = false,
                    Errors = { "玩家不在死亡状态" }
                };
            }

            // 检查复活时间是否已到
            var stateKey = string.Format(RedisKeys.PlayerState, gameId, playerId);
            var stateData = await _redisService.GetHashAllAsync(stateKey);
            
            if (stateData.TryGetValue("respawn_time", out var respawnTimeStr) && 
                DateTime.TryParse(respawnTimeStr, out var respawnTime))
            {
                if (DateTime.UtcNow < respawnTime)
                {
                    var remainingTime = respawnTime - DateTime.UtcNow;
                    return new RespawnResult
                    {
                        Success = false,
                        Errors = { $"复活冷却中，还需等待 {remainingTime.TotalSeconds:F1} 秒" }
                    };
                }
            }

            // 设置复活位置（回到出生点）
            var respawnPosition = playerState.SpawnPoint;
            var invulnerabilityEndTime = DateTime.UtcNow.AddSeconds(GameConstants.InvulnerabilityDuration);

            // 更新玩家状态
            var respawnUpdates = new Dictionary<string, string>
            {
                ["current_position"] = JsonSerializer.Serialize(respawnPosition),
                ["state"] = PlayerDrawingState.Invulnerable.ToString(),
                ["is_invulnerable"] = "true",
                ["invulnerability_end"] = invulnerabilityEndTime.ToString("O"),
                ["last_activity"] = DateTime.UtcNow.ToString("O")
            };
            await _redisService.SetHashMultipleAsync(stateKey, respawnUpdates);

            // 清除死亡相关数据
            await _redisService.HashDeleteAsync(stateKey, "death_position");
            await _redisService.HashDeleteAsync(stateKey, "respawn_time");

            // 安排无敌状态结束
            _ = Task.Delay(TimeSpan.FromSeconds(GameConstants.InvulnerabilityDuration))
                .ContinueWith(async _ => await EndInvulnerabilityAsync(gameId, playerId));

            _logger.LogInformation("玩家复活成功 - GameId: {GameId}, PlayerId: {PlayerId}, InvulnerabilityEnd: {InvulEnd}", 
                gameId, playerId, invulnerabilityEndTime);

            return new RespawnResult
            {
                Success = true,
                RespawnPosition = respawnPosition,
                InvulnerabilityEndTime = invulnerabilityEndTime,
                Messages = { $"复活成功，{GameConstants.InvulnerabilityDuration}秒无敌保护" }
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "复活玩家失败 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
            return new RespawnResult
            {
                Success = false,
                Errors = { "复活时发生内部错误" }
            };
        }
    }

    #endregion

    #region 领地和排名系统

    /// <summary>
    /// 计算玩家当前总领地面积
    /// </summary>
    public async Task<TerritoryResult> CalculatePlayerTerritoryAsync(Guid gameId, Guid playerId)
    {
        try
        {
            _logger.LogDebug("计算玩家领地面积 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);

            // 获取玩家拥有的所有领地
            var territories = await GetPlayerTerritoriesAsync(gameId, playerId);
            
            if (!territories.Any())
            {
                return new TerritoryResult
                {
                    Success = true,
                    TotalArea = 0f,
                    TerritoryCount = 0,
                    AreaPercentage = 0f,
                    Messages = { "玩家没有领地" }
                };
            }

            // 计算总面积（重新计算以确保准确性）
            float totalArea = 0f;
            var validTerritories = new List<Territory>();

            foreach (var territory in territories)
            {
                // 重新计算每块领地的面积
                var recalculatedArea = CalculatePolygonArea(territory.Boundary);
                if (recalculatedArea >= GameConstants.MinTerritoryArea)
                {
                    territory.Area = recalculatedArea;
                    totalArea += recalculatedArea;
                    validTerritories.Add(territory);
                }
            }

            // 计算面积百分比（假设地图总面积为1000x1000）
            const float mapTotalArea = 1000f * 1000f;
            var areaPercentage = (totalArea / mapTotalArea) * 100f;

            // 更新Redis中的领地面积
            await UpdatePlayerTerritoryAreaAsync(gameId, playerId, totalArea);

            return new TerritoryResult
            {
                Success = true,
                TotalArea = totalArea,
                Territories = validTerritories,
                TerritoryCount = validTerritories.Count,
                AreaPercentage = areaPercentage,
                Messages = { $"总领地面积：{totalArea:F1}，占比：{areaPercentage:F2}%" }
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "计算玩家领地面积失败 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
            return new TerritoryResult
            {
                Success = false,
                Messages = { "计算领地面积时发生内部错误" }
            };
        }
    }

    /// <summary>
    /// 获取游戏实时排名
    /// </summary>
    public async Task<List<PlayerGameRanking>> GetGameRankingAsync(Guid gameId)
    {
        try
        {
            _logger.LogDebug("获取游戏排名 - GameId: {GameId}", gameId);

            // 获取所有玩家状态
            var allPlayers = await GetAllPlayerStatesAsync(gameId);

            // 重新计算每个玩家的领地面积
            var rankings = new List<PlayerGameRanking>();

            foreach (var player in allPlayers)
            {
                var territoryResult = await CalculatePlayerTerritoryAsync(gameId, player.PlayerId);
                
                var ranking = new PlayerGameRanking
                {
                    PlayerId = player.PlayerId,
                    PlayerName = player.PlayerName,
                    PlayerColor = player.PlayerColor,
                    TerritoryArea = territoryResult.TotalArea,
                    TerritoryCount = territoryResult.TerritoryCount,
                    AreaPercentage = territoryResult.AreaPercentage,
                    CurrentState = player.State,
                    LastUpdate = DateTime.UtcNow
                };

                rankings.Add(ranking);
            }

            // 按领地面积排序
            rankings.Sort((a, b) => b.TerritoryArea.CompareTo(a.TerritoryArea));

            // 分配排名
            for (int i = 0; i < rankings.Count; i++)
            {
                rankings[i].Rank = i + 1;
            }

            // 保存排名到Redis
            var rankingKey = string.Format(RedisKeys.GameRanking, gameId);
            await _redisService.KeyDeleteAsync(rankingKey);
            
            foreach (var ranking in rankings)
            {
                await _redisService.ListRightPushAsync(rankingKey, JsonSerializer.Serialize(ranking));
            }

            _logger.LogDebug("游戏排名计算完成 - GameId: {GameId}, PlayerCount: {Count}", gameId, rankings.Count);
            return rankings;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取游戏排名失败 - GameId: {GameId}", gameId);
            return new List<PlayerGameRanking>();
        }
    }

    #endregion

    #region 道具系统

    /// <summary>
    /// 玩家拾取地图上的道具
    /// </summary>
    public async Task<ItemPickupResult> PickupItemAsync(
        Guid gameId, 
        Guid playerId, 
        Guid itemId, 
        Position pickupPosition)
    {
        try
        {
            _logger.LogInformation("玩家拾取道具 - GameId: {GameId}, PlayerId: {PlayerId}, ItemId: {ItemId}", 
                gameId, playerId, itemId);

            // 获取玩家状态
            var playerState = await GetPlayerStateAsync(gameId, playerId);
            if (playerState == null)
            {
                return new ItemPickupResult
                {
                    Success = false,
                    Errors = { "玩家不存在" }
                };
            }

            // 检查玩家是否存活且不在无敌状态
            if (playerState.State == PlayerDrawingState.Dead || playerState.State == PlayerDrawingState.Respawning)
            {
                return new ItemPickupResult
                {
                    Success = false,
                    Errors = { "死亡状态下无法拾取道具" }
                };
            }

            // 检查玩家位置是否接近道具
            var distance = CalculateDistance(playerState.CurrentPosition, pickupPosition);
            if (distance > GameConstants.PickupRange)
            {
                return new ItemPickupResult
                {
                    Success = false,
                    Errors = { $"距离道具太远：{distance:F1} > {GameConstants.PickupRange}" }
                };
            }

            // 检查背包是否已满
            if (playerState.Inventory.Count >= GameConstants.MaxInventorySize)
            {
                return new ItemPickupResult
                {
                    Success = false,
                    InventoryFull = true,
                    Errors = { "背包已满" }
                };
            }

            // 模拟道具类型（实际应从道具服务获取）
            var itemType = DetermineItemType(itemId);

            // 添加道具到背包
            var inventoryKey = string.Format(RedisKeys.PlayerInventory, gameId, playerId);
            await _redisService.ListRightPushAsync(inventoryKey, itemType.ToString());

            // 更新统计
            await UpdatePlayerStatisticsAsync(gameId, playerId, stats =>
            {
                stats.ItemsPickedUp++;
                stats.LastActivity = DateTime.UtcNow;
            });

            _logger.LogInformation("道具拾取成功 - GameId: {GameId}, PlayerId: {PlayerId}, ItemType: {ItemType}", 
                gameId, playerId, itemType);

            return new ItemPickupResult
            {
                Success = true,
                ItemId = itemId,
                ItemType = itemType,
                PickupPosition = pickupPosition,
                NewItemCount = playerState.Inventory.Count + 1,
                Messages = { $"拾取了 {itemType} 道具" }
            };
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "拾取道具失败 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
            return new ItemPickupResult
            {
                Success = false,
                Errors = { "拾取道具时发生内部错误" }
            };
        }
    }

    /// <summary>
    /// 玩家使用背包中的道具
    /// </summary>
    public async Task<ItemUseResult> UseItemAsync(
        Guid gameId, 
        Guid playerId, 
        DrawingGameItemType itemType, 
        Position? targetPosition = null)
    {
        try
        {
            _logger.LogInformation("玩家使用道具 - GameId: {GameId}, PlayerId: {PlayerId}, ItemType: {ItemType}", 
                gameId, playerId, itemType);

            // 获取玩家状态
            var playerState = await GetPlayerStateAsync(gameId, playerId);
            if (playerState == null)
            {
                return new ItemUseResult
                {
                    Success = false,
                    Errors = { "玩家不存在" }
                };
            }

            // 检查玩家状态
            if (playerState.State == PlayerDrawingState.Dead || playerState.State == PlayerDrawingState.Respawning)
            {
                return new ItemUseResult
                {
                    Success = false,
                    Errors = { "死亡状态下无法使用道具" }
                };
            }

            // 检查背包中是否有该道具
            if (!playerState.Inventory.Contains(itemType))
            {
                return new ItemUseResult
                {
                    Success = false,
                    Errors = { "背包中没有该道具" }
                };
            }

            var result = new ItemUseResult
            {
                Success = true,
                ItemType = itemType
            };

            // 根据道具类型执行不同逻辑
            switch (itemType)
            {
                case DrawingGameItemType.Lightning:
                    result = await UseLightningItemAsync(gameId, playerId);
                    break;

                case DrawingGameItemType.Shield:
                    result = await UseShieldItemAsync(gameId, playerId);
                    break;

                case DrawingGameItemType.Bomb:
                    if (targetPosition == null)
                    {
                        result.Success = false;
                        result.Errors.Add("炸弹道具需要指定目标位置");
                        break;
                    }
                    result = await UseBombItemAsync(gameId, playerId, targetPosition);
                    break;

                default:
                    result.Success = false;
                    result.Errors.Add("未知的道具类型");
                    break;
            }

            // 如果使用成功，从背包中移除道具
            if (result.Success)
            {
                await RemoveItemFromInventoryAsync(gameId, playerId, itemType);
                
                // 更新统计
                await UpdatePlayerStatisticsAsync(gameId, playerId, stats =>
                {
                    stats.ItemsUsed++;
                    stats.LastActivity = DateTime.UtcNow;
                });
            }

            return result;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "使用道具失败 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
            return new ItemUseResult
            {
                Success = false,
                Errors = { "使用道具时发生内部错误" }
            };
        }
    }

    #endregion

    #region 道具使用私有方法

    /// <summary>
    /// 使用闪电道具
    /// </summary>
    private async Task<ItemUseResult> UseLightningItemAsync(Guid gameId, Guid playerId)
    {
        var effect = new ActiveEffect
        {
            Id = Guid.NewGuid(),
            EffectType = DrawingGameItemType.Lightning,
            StartTime = DateTime.UtcNow,
            Duration = TimeSpan.FromSeconds(10),
            Properties = { ["speed_multiplier"] = 1.5f }
        };

        await AddPlayerEffectAsync(gameId, playerId, effect);

        return new ItemUseResult
        {
            Success = true,
            ItemType = DrawingGameItemType.Lightning,
            AppliedEffect = effect,
            Messages = { "闪电效果已激活，移动速度提升50%，持续10秒" }
        };
    }

    /// <summary>
    /// 使用护盾道具
    /// </summary>
    private async Task<ItemUseResult> UseShieldItemAsync(Guid gameId, Guid playerId)
    {
        var effect = new ActiveEffect
        {
            Id = Guid.NewGuid(),
            EffectType = DrawingGameItemType.Shield,
            StartTime = DateTime.UtcNow,
            Duration = TimeSpan.FromSeconds(15),
            Properties = { ["blocks_remaining"] = 1 }
        };

        await AddPlayerEffectAsync(gameId, playerId, effect);

        return new ItemUseResult
        {
            Success = true,
            ItemType = DrawingGameItemType.Shield,
            AppliedEffect = effect,
            Messages = { "护盾效果已激活，可抵挡一次攻击，持续15秒" }
        };
    }

    /// <summary>
    /// 使用炸弹道具
    /// </summary>
    private async Task<ItemUseResult> UseBombItemAsync(Guid gameId, Guid playerId, Position targetPosition)
    {
        // 获取附近的玩家轨迹并清除
        var affectedPlayers = new List<Guid>();
        var clearedTrails = new List<Position>();

        // 获取所有玩家
        var allPlayers = await GetAllPlayerStatesAsync(gameId);
        
        // 检查爆炸范围内的轨迹
        foreach (var player in allPlayers)
        {
            if (player.PlayerId == playerId) continue; // 不影响自己
            
            if (player.State == PlayerDrawingState.Drawing)
            {
                var trail = await GetPlayerTrailAsync(gameId, player.PlayerId);
                bool hasNearbyTrail = trail.Any(pos => CalculateDistance(pos, targetPosition) <= 100f);
                
                if (hasNearbyTrail)
                {
                    // 清除该玩家的轨迹
                    await ClearPlayerTrailAsync(gameId, player.PlayerId);
                    await UpdatePlayerStateInRedisAsync(gameId, player.PlayerId, PlayerDrawingState.Idle);
                    
                    affectedPlayers.Add(player.PlayerId);
                    clearedTrails.AddRange(trail.Where(pos => CalculateDistance(pos, targetPosition) <= 100f));
                }
            }
        }

        _logger.LogInformation("炸弹在位置 ({X},{Y}) 爆炸，影响了 {Count} 个玩家", 
            targetPosition.X, targetPosition.Y, affectedPlayers.Count);

        return new ItemUseResult
        {
            Success = true,
            ItemType = DrawingGameItemType.Bomb,
            TargetPosition = targetPosition,
            AffectedPlayers = affectedPlayers,
            ClearedTrails = clearedTrails,
            Messages = { $"炸弹在位置 ({targetPosition.X:F0},{targetPosition.Y:F0}) 爆炸，影响了 {affectedPlayers.Count} 个玩家" }
        };
    }

    #endregion

    #region 更多私有辅助方法

    /// <summary>
    /// 移除玩家效果
    /// </summary>
    private async Task RemovePlayerEffectAsync(Guid gameId, Guid playerId, Guid effectId)
    {
        try
        {
            var effectsKey = string.Format(RedisKeys.PlayerEffects, gameId, playerId);
            var effectsData = await _redisService.ListRangeAsync(effectsKey);
            
            // 重建效果列表，移除指定效果
            await _redisService.KeyDeleteAsync(effectsKey);
            
            foreach (var effectData in effectsData)
            {
                try
                {
                    var effect = JsonSerializer.Deserialize<ActiveEffect>(effectData);
                    if (effect?.Id != effectId)
                    {
                        await _redisService.ListRightPushAsync(effectsKey, effectData);
                    }
                }
                catch
                {
                    // 忽略无效的效果数据
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "移除玩家效果失败 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
        }
    }

    /// <summary>
    /// 清除玩家临时效果
    /// </summary>
    private async Task ClearPlayerTemporaryEffectsAsync(Guid gameId, Guid playerId)
    {
        try
        {
            var effectsKey = string.Format(RedisKeys.PlayerEffects, gameId, playerId);
            await _redisService.KeyDeleteAsync(effectsKey);
            _logger.LogDebug("已清除玩家临时效果 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "清除玩家临时效果失败 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
        }
    }

    /// <summary>
    /// 结束无敌状态
    /// </summary>
    private async Task EndInvulnerabilityAsync(Guid gameId, Guid playerId)
    {
        try
        {
            var stateKey = string.Format(RedisKeys.PlayerState, gameId, playerId);
            var updates = new Dictionary<string, string>
            {
                ["is_invulnerable"] = "false",
                ["state"] = PlayerDrawingState.Idle.ToString(),
                ["last_activity"] = DateTime.UtcNow.ToString("O")
            };

            await _redisService.SetHashMultipleAsync(stateKey, updates);
            await _redisService.HashDeleteAsync(stateKey, "invulnerability_end");

            _logger.LogDebug("无敌状态已结束 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "结束无敌状态失败 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
        }
    }

    /// <summary>
    /// 确定道具类型（模拟方法）
    /// </summary>
    private static DrawingGameItemType DetermineItemType(Guid itemId)
    {
        // 简化实现：根据ID哈希值确定道具类型
        var hash = itemId.GetHashCode();
        var itemTypes = Enum.GetValues<DrawingGameItemType>();
        return itemTypes[Math.Abs(hash) % itemTypes.Length];
    }

    /// <summary>
    /// 从背包移除道具
    /// </summary>
    private async Task RemoveItemFromInventoryAsync(Guid gameId, Guid playerId, DrawingGameItemType itemType)
    {
        try
        {
            var inventoryKey = string.Format(RedisKeys.PlayerInventory, gameId, playerId);
            var inventoryData = await _redisService.ListRangeAsync(inventoryKey);
            
            // 重建背包，移除一个指定类型的道具
            await _redisService.KeyDeleteAsync(inventoryKey);
            bool removed = false;
            
            foreach (var itemData in inventoryData)
            {
                if (!removed && Enum.TryParse<DrawingGameItemType>(itemData, out var currentItemType) && currentItemType == itemType)
                {
                    removed = true; // 跳过第一个匹配的道具
                    continue;
                }
                await _redisService.ListRightPushAsync(inventoryKey, itemData);
            }

            _logger.LogDebug("已从背包移除道具 - GameId: {GameId}, PlayerId: {PlayerId}, ItemType: {ItemType}", 
                gameId, playerId, itemType);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "从背包移除道具失败 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
        }
    }

    /// <summary>
    /// 添加玩家效果
    /// </summary>
    private async Task AddPlayerEffectAsync(Guid gameId, Guid playerId, ActiveEffect effect)
    {
        try
        {
            var effectsKey = string.Format(RedisKeys.PlayerEffects, gameId, playerId);
            var effectData = JsonSerializer.Serialize(effect);
            await _redisService.ListRightPushAsync(effectsKey, effectData);

            _logger.LogDebug("已添加玩家效果 - GameId: {GameId}, PlayerId: {PlayerId}, EffectType: {EffectType}", 
                gameId, playerId, effect.EffectType);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "添加玩家效果失败 - GameId: {GameId}, PlayerId: {PlayerId}", gameId, playerId);
        }
    }

    #endregion
}
